// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This script generates all FFIGEN-based bindings we require to use JNI, which
// includes some C wrappers over `JNIEnv` type and some Dart extension methods.

import 'dart:io';

import 'package:args/args.dart';
import 'package:ffigen/ffigen.dart' as ffigen;
import 'package:ffigen/src/header_parser.dart' as ffigen;
import 'package:logging/logging.dart';

import 'wrapper_generators/generate_c_extensions.dart';
import 'wrapper_generators/generate_dart_extensions.dart';
import 'wrapper_generators/logging.dart';

void main(List<String> args) {
  final levels = Map.fromEntries(
    Level.LEVELS.map((l) => MapEntry(l.name.toLowerCase(), l)),
  );
  final argParser = ArgParser()
    ..addOption(
      'verbose',
      defaultsTo: 'severe',
      help: 'set ffigen log verbosity',
      allowed: levels.keys,
    )
    ..addFlag(
      'help',
      negatable: false,
      abbr: 'h',
      defaultsTo: false,
      help: 'display this help message',
    );

  final argResults = argParser.parse(args);

  if (argResults['help'] as bool) {
    stderr.writeln('Generates FFI bindings required for package:jni');
    stderr.writeln(argParser.usage);
    exitCode = 1;
    return;
  }

  hierarchicalLoggingEnabled = true;
  Logger.root.level = levels[argResults['verbose']]!;
  logger.level = Level.INFO;
  Logger.root.onRecord.listen((record) {
    stderr.writeln('${record.level.name}: ${record.message}');
  });

  logger.info('Generating minimal C wrappers for HarmonyOS Napi (global_napi_env.*)');
  // 为与 Android 侧命名统一，生成 global_napi_env.{h,c}
  // 仅包含全局 env 及若干常用薄封装
  // 这里不依赖 ffigen 解析 N-API 结构
  // 直接生成 minimal C wrappers（无需 ffigen Library）
  generateCWrappers();
  // 直接生成 minimal C wrappers（无需 ffigen Library）
  logger.info('Generating FFI bindings for package:napi');

  logger.info('Generating FFI bindings for package:napi');

  final config = ffigen.YamlConfig.fromFile(File('ffigen.yaml'));
  final library = ffigen.parse(config);
  final outputFile = File(config.output.toFilePath());
  // 生成 HarmonyOS 版 global_env_extensions.dart（Dart 侧薄封装）
  try {
    generateDartExtensions(library);
  } catch (e) {
    logger.warning('generateDartExtensions failed (non-fatal): $e');
  }

  logger.info('HarmonyOS Napi generation completed');
  // Note: HarmonyOS Napi uses direct function calls, not interface structs
  // like Android JNI, so we don't need to generate global_env_extensions.dart
  // The napi_bindings_generated.dart file contains all necessary bindings
  logger.info('HarmonyOS Napi generation completed');
  // like Android JNI, so we don't need to generate global_env_extensions.dart
  // The napi_bindings_generated.dart file contains all necessary bindings
}
